package com.hongpu.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hongpu.domain.HpProjectWorkPay;
import com.hongpu.domain.HpProjectWorkPayList;
import com.hongpu.dto.ProjectWorkPayDto1;
import com.hongpu.enums.IncomeAndExpenditureTypesEnum;
import com.hongpu.mapper.HpProjectWorkPayListMapper;
import com.hongpu.mapper.HpProjectWorkPayMapper;
import com.hongpu.service.HpProjectWorkPayListService;
import com.hongpu.service.HpProjectWorkPayService;
import com.hongpu.vo.HpProjectWorkPayVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;


/**
* @author Michael zhang
* @description 针对表【hp_project_work_pay(项目的回款与支出)】的数据库操作Service实现
* @createDate 2025-04-25 21:03:15
*/
@Service
@Slf4j
public class HpProjectWorkPayServiceImpl extends ServiceImpl<HpProjectWorkPayMapper, HpProjectWorkPay>
    implements HpProjectWorkPayService{
    @Autowired
    HpProjectWorkPayMapper baseMapper;
    @Autowired
    HpProjectWorkPayListService hpProjectWorkPayListService;
    @Autowired
    HpProjectWorkPayListMapper hpProjectWorkPayListMapper;
    private static final String DEFAULT_PROJECTNAME = "null";



    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(HpProjectWorkPay hpProjectWorkPay) {
        try {
            // 根据项目ID和收入或支出标识删除存在的数据,然后再执行保存
            HpProjectWorkPay workPay = getHpProjectWorkPay(hpProjectWorkPay.getProjectId(), hpProjectWorkPay.getIncomeAndExpenditureTypes());
            // 默认值 false表示hpProjectWorkPay对象需要存储
            boolean oprateFlag = false;
            if(workPay != null){
                oprateFlag = true;
                hpProjectWorkPay.setId(workPay.getId());
            }else {
                oprateFlag = save(hpProjectWorkPay);
            }
            if(oprateFlag){
                Long id = hpProjectWorkPay.getId();
                List<HpProjectWorkPayList> hpProjectWorkPayLists = hpProjectWorkPay.getHpProjectWorkPayLists();
               if(!CollectionUtils.isEmpty(hpProjectWorkPayLists)){
                   BigDecimal totalContractAmount = new BigDecimal(0);
                   for (HpProjectWorkPayList hpProjectWorkPayList : hpProjectWorkPayLists) {
                       Long hpProjectWorkPayListId = hpProjectWorkPayList.getId();
                       if(hpProjectWorkPayListId != null){
                           hpProjectWorkPayListService.removeById(hpProjectWorkPayListId);
                       }
                       hpProjectWorkPayList.setProjectWorkPayId(id);
                       totalContractAmount = totalContractAmount.add(hpProjectWorkPayList.getContractAmount());
                   }
                   // 将hpProjectWorkPayList中的contract_amount统计加和后，更新hp_project_work_pay中total_contract_amount
                   baseMapper.updateTotalContractAmount(totalContractAmount, id);
                   hpProjectWorkPayListService.saveBatch(hpProjectWorkPayLists);
               }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 分页
     *
     * @param hpProjectWorkPay
     */
    @Override
    public IPage<HpProjectWorkPayVo> selectPage(IPage<?> page,String projectName) {
        // 根据项目名去重查询的分页，集合中项目名称唯一
        IPage<HpProjectWorkPayVo> selectPage = baseMapper.page(page, projectName);
        List<HpProjectWorkPayVo> records = selectPage.getRecords();
        // 根据项目名称查询所有主数据ID
        for (HpProjectWorkPayVo hpProjectWorkPayVo : records){
            String name = hpProjectWorkPayVo.getProjectName();
            List<ProjectWorkPayDto1> projectWorkPayDto1s = baseMapper.selectIdByProjectName(name);
            for (ProjectWorkPayDto1 projectWorkPayDto1 : projectWorkPayDto1s) {
                Long id = projectWorkPayDto1.getId();
                String incomeAndExpenditureTypes = projectWorkPayDto1.getIncomeAndExpenditureTypes();
                // 处理收入业务
                if(IncomeAndExpenditureTypesEnum.INCOME.getValue().equals(incomeAndExpenditureTypes)){
                    // 根据 projectWorkPayId 和incomeAndExpenditureTypes 查询付款合同总额
                    HpProjectWorkPayVo paidSum = hpProjectWorkPayListMapper.getPaidSum(id);
                    if(paidSum != null){
                        hpProjectWorkPayVo.setInPaid(paidSum.getInPaid());
                        hpProjectWorkPayVo.setInUnpaid(paidSum.getInUnpaid());
                    }
                    BigDecimal totalContractAmount = hpProjectWorkPayListMapper.getInTotalContractAmount(id);
                    if(totalContractAmount == null){
                        totalContractAmount = BigDecimal.ZERO;
                    }
                    hpProjectWorkPayVo.setInTotalContractAmount(totalContractAmount);
                }else if(IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)){
                    HpProjectWorkPayVo unPaidSum = hpProjectWorkPayListMapper.getUnPaidSum(id);
                    if(unPaidSum != null){
                        hpProjectWorkPayVo.setOutTotalContractAmount(unPaidSum.getOutTotalContractAmount());
                    }
                }else {
                    log.info("无法判断项目ID{}的收入和支出标识,请检查主数据完整性", id);
                }
            }
            // 毛利润=合同金额-已支付
            BigDecimal surplus = hpProjectWorkPayVo.getInTotalContractAmount().subtract(hpProjectWorkPayVo.getOutTotalContractAmount());
            hpProjectWorkPayVo.setSurplus(surplus);
            // 当前差额 = 已收款-已支付
            BigDecimal currentSurplus = hpProjectWorkPayVo.getInPaid().subtract(hpProjectWorkPayVo.getOutTotalContractAmount());
            hpProjectWorkPayVo.setCurrentSurplus(currentSurplus);
        }
        return selectPage;
    }

    @Override
    public List<HpProjectWorkPayVo> selectList(String projectName) {
        if(DEFAULT_PROJECTNAME.equals(projectName)){
            projectName = null;
        }
        List<HpProjectWorkPayVo> list = baseMapper.list(projectName);
        // 根据项目名称查询所有主数据ID
        for (HpProjectWorkPayVo hpProjectWorkPayVo : list){
            String name = hpProjectWorkPayVo.getProjectName();
            List<ProjectWorkPayDto1> projectWorkPayDto1s = baseMapper.selectIdByProjectName(name);
            for (ProjectWorkPayDto1 projectWorkPayDto1 : projectWorkPayDto1s) {
                Long id = projectWorkPayDto1.getId();
                String incomeAndExpenditureTypes = projectWorkPayDto1.getIncomeAndExpenditureTypes();
                // 处理收入业务
                if(IncomeAndExpenditureTypesEnum.INCOME.getValue().equals(incomeAndExpenditureTypes)){
                    // 根据 projectWorkPayId 和incomeAndExpenditureTypes 查询付款合同总额
                    HpProjectWorkPayVo paidSum = hpProjectWorkPayListMapper.getPaidSum(id);
                    if(paidSum != null){
                        hpProjectWorkPayVo.setInTotalContractAmount(paidSum.getInTotalContractAmount());
                        hpProjectWorkPayVo.setInPaid(paidSum.getInPaid());
                        hpProjectWorkPayVo.setInUnpaid(paidSum.getInUnpaid());
                    }
                }else if(IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)){
                    HpProjectWorkPayVo unPaidSum = hpProjectWorkPayListMapper.getUnPaidSum(id);
                    if(unPaidSum != null){
                        hpProjectWorkPayVo.setOutTotalContractAmount(unPaidSum.getOutTotalContractAmount());
                    }
                }else {
                    log.info("无法判断项目ID{}的收入和支出标识,请检查主数据完整性", id);
                }
            }
            // 剩余金额 = 收入合同总额 - 支出合同总额
            hpProjectWorkPayVo.setSurplus(hpProjectWorkPayVo.getInTotalContractAmount().subtract(hpProjectWorkPayVo.getOutTotalContractAmount()));
        }
        return list;
    }

    /**
     * 根据项目ID和收入或支出标识删除存在的数据
     *
     * @param projectId
     * @param incomeAndExpenditureTypes
     */
    @Override
    public HpProjectWorkPay getHpProjectWorkPay(Long projectId, String incomeAndExpenditureTypes) {
        return baseMapper.getHpProjectWorkPay(projectId, incomeAndExpenditureTypes);
    }

    /**
     * 根据项目ID删除主数据
     *
     * @param projectId
     */
    @Override
    public boolean deleteByProjectId(Long projectId) {
        return baseMapper.deleteByProjectId(projectId);
    }

    @Override
    public boolean deleteById(Long id) {
        try  {
            if(id == null){
                return false;
            }
            // 子表删除
            hpProjectWorkPayListService.deleteByProjectWorkPayId(id);
            // 主表删除
            baseMapper.deleteById(id);
           return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 当项目管理模块新增一个项目时，需要同时新增一条收款和支付记录
     * @param projectId
     * @param project_name
     * @param projectAmount  项目金额或合同总额，仅用于收款时使用
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addProjectWorkPay(Long projectId,String projectName, BigDecimal projectAmount) {
        try {
            // 收款主数据
            HpProjectWorkPay shouKuan = new HpProjectWorkPay();
            shouKuan.setProjectId(projectId);
            shouKuan.setProjectName(projectName);
            shouKuan.setIncomeAndExpenditureTypes(IncomeAndExpenditureTypesEnum.INCOME.getValue());
            shouKuan.setTotalContractAmount(projectAmount);
            save(shouKuan);
            // 支付主数据
            HpProjectWorkPay zhifu = new HpProjectWorkPay();
            zhifu.setProjectId(projectId);
            zhifu.setProjectName(projectName);
            zhifu.setIncomeAndExpenditureTypes(IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue());
            zhifu.setTotalContractAmount(new BigDecimal(0));
            save(zhifu);
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据项目ID修改项目名称
     *
     * @param projectId
     * @param projectName
     */
    @Override
    public boolean updateProjectName(Long projectId, String projectName,BigDecimal projectAmount) {
        return baseMapper.updateProjectName(projectId,projectName,projectAmount);
    }
}




